
from rest_framework import serializers, status
from typing import List, Tuple, Union

from rest_framework.response import Response
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from rest_framework_simplejwt.tokens import RefreshToken, T, AuthUser

from user.models import User


class DynamicFieldsModelSerializer(serializers.ModelSerializer):

    def __init__(self, *args, **kwargs):

        fields: Union[List[str], Tuple[str, ...]] = kwargs.pop('fields', [])

        excludes: Union[List[str], Tuple[str, ...]] = kwargs.pop('exclude', [])

        assert not (fields and excludes), "fields 和 excludes 是互斥的、 不允许 同时存在"

        super().__init__(*args, **kwargs)

        if fields:
            allowed = set(fields)
            existing = set(self.fields)
            for field_name in existing - allowed:
                self.fields.pop(field_name)

        if excludes:
            for field_name in excludes:
                self.fields.pop(field_name)
class MyRefreshToken(RefreshToken):
    @classmethod
    def for_user(cls: type[T], user: AuthUser) -> T:
        token = super().for_user(user)

        token['is_staff'] = user.is_staff
        token['username'] = user.username
        token['name'] = user.name
        token['clazz_id'] = user.clazz_id
        if user.clazz:
            token['className'] = user.clazz.name
        else:
            token['className'] = "暂无"

        if user.is_superuser:
            token['roleName'] = "超级管理员"
        elif user.role:
            token['roleName'] = user.role.name
        else:
            token['roleName'] = '普通用户'
        if user.tel:
            token['tel'] = user.tel[:3] + "****" + user.tel[-4:]
        else:
            token['tel'] = "暂无"
        return token


# 创建用于jwt登录的序列化器
class CustomTokenObtainPairSerializer(TokenObtainPairSerializer):
    @classmethod
    def get_token(cls, user: User) -> RefreshToken:
        token = super().get_token(user)

        # 添加自定义声明（claims）
        token['username'] = user.username
        token['email'] = user.email
        token['is_staff'] = user.is_staff
        token['is_superuser'] = user.is_superuser

        # 如果有自定义用户模型字段，也可以添加
        if hasattr(user, 'role'):
            token['role'] = user.role

        return token


class RegisterSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['username', 'password', 'email', 'name', 'tel', 'role', 'clazz']
        extra_kwargs = {
            'password': {'write_only': True},
            'email': {'required': True},
            'name': {'required': True},
            'tel': {'required': True},
            'role': {'required': True},
            'clazz': {'required': True},
        }

    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        user = serializer.validated_data
        refresh = MyRefreshToken.for_user(user)
        return Response({
            "refresh": str(refresh),
            "access": str(refresh.access_token),
        }, status=status.HTTP_200_OK)

    def validate_username(self, value):
        # 检查用户名是否已存在
        if User.objects.filter(username=value).exists():
            # 如果存在，则抛出异常
            raise serializers.ValidationError("用户名已存在")
        # 如果不存在，则返回用户名
        return value


# 创建一个用户管理的序列化器
class UserSerializer(DynamicFieldsModelSerializer):
    class Meta:
        model = User
        fields = ['id', 'username', 'email', 'password', 'tel']  # 指定安全字段
        extra_kwargs = {'password': {'write_only': True}}  # 隐藏密码返回
